package pkg

import (
	"github.com/apache/rocketmq-clients/golang/v5"
	"github.com/apache/rocketmq-clients/golang/v5/credentials"
	"os"
	"time"
)

type RocketmqConfig struct {
	Endpoint     string `yaml:"endpoint" mapstructure:"endpoint"`
	AccessKey    string `yaml:"accessKey" mapstructure:"accessKey"`
	AccessSecret string `yaml:"accessSecret" mapstructure:"accessSecret"`
}

type Rocketmq struct {
	RocketmqConfig   RocketmqConfig
	TransactionTopic string
	AwaitDuration    time.Duration
}

func RocketmqInit(rocketmqConfig RocketmqConfig) (*Rocketmq, error) {
	return &Rocketmq{
		RocketmqConfig:   rocketmqConfig,
		TransactionTopic: "transaction",
		AwaitDuration:    time.Second * 5,
	}, nil
}

// NewSimpleConsumer 创建消费者
func (rocketmq *Rocketmq) NewSimpleConsumer(Topic string, ConsumerGroup string) (golang.SimpleConsumer, error) {
	os.Setenv("mq.consoleAppender.enabled", "true")
	golang.ResetLogger()
	// In most case, you don't need to create many consumers, singleton pattern is more recommended.
	return golang.NewSimpleConsumer(
		&golang.Config{
			Endpoint:      rocketmq.RocketmqConfig.Endpoint,
			ConsumerGroup: ConsumerGroup,
			Credentials: &credentials.SessionCredentials{
				AccessKey:    rocketmq.RocketmqConfig.AccessKey,
				AccessSecret: rocketmq.RocketmqConfig.AccessSecret,
			},
		},
		golang.WithAwaitDuration(rocketmq.AwaitDuration),
		golang.WithSubscriptionExpressions(map[string]*golang.FilterExpression{
			Topic: golang.SUB_ALL,
		}),
	)
}

// NewTransactionProducer 创建事务消息，生产者
func (rocketmq *Rocketmq) NewTransactionProducer(transactionChecker *golang.TransactionChecker) (golang.Producer, error) {
	// log to console
	os.Setenv("mq.consoleAppender.enabled", "true")
	golang.ResetLogger()
	// In most case, you don't need to create many producers, singleton pattern is more recommended.
	return golang.NewProducer(
		&golang.Config{
			Endpoint: rocketmq.RocketmqConfig.Endpoint,
			Credentials: &credentials.SessionCredentials{
				AccessKey:    rocketmq.RocketmqConfig.AccessKey,
				AccessSecret: rocketmq.RocketmqConfig.AccessSecret,
			},
		},
		// 定义 MQ 回查方法，用于 MQ 异常后收不到消息，而回查订单是否支付成功
		//golang.WithTransactionChecker(&golang.TransactionChecker{
		//	Check: func(msg *golang.MessageView) golang.TransactionResolution {
		//		log.Printf("check transaction message: %v", msg)
		//		if true { // 支付成功
		//			return golang.COMMIT
		//		} else { // 支付失败
		//			return golang.ROLLBACK
		//		}
		//	},
		//}),
		golang.WithTransactionChecker(transactionChecker),
		golang.WithTopics(rocketmq.TransactionTopic),
	)
}
